--[[
@classmod Palette
]]

local lume = require (LIB_PATH.."lume")
local _lf = _lf
local _li = _li
local _lm = _lm
local _lg = _lg

return pl.class {
   _init = function (self, colors, s)
	self.sz = s or 48
      self.show = false
      self.tile_margin = 2
      self.x, self.y = 0, 0
      self.offsetY = 0
      self.selected_id = 1
      self.hovered_id = nil
      if not colors then self:import_from_file () end
      self:compute_size()
   end,

   compute_size = function (self)
		self.y = self.offsetY
       if #self.colors < self.tile_margin then
		 self.w = #self.colors
		 self.h = 1
      else
		 self.w = self.tile_margin
		 self.h = math.floor(#self.colors/self.tile_margin)
      end
      self.pw, self.ph = self.x+self.w * self.sz, self.y + self.h * self.sz
      self.pixel_margin = self.tile_margin * self.sz
   end,
   
   get_bounds = function (self)
	return self.x, self.y, self.pw, self.ph
   end,
   
   import_from_file = function (self, _file)
      local f = _file or "endesga.png"
      local file = "assets/palettes/".. f
      if not _lf.getInfo(file) then
	 return "File doesn't exist"
      end
      local data = _li.newImageData(file)
      local colors = {}
      local extract_color = function (_x, _y, r, g, b, a)
	 table.insert(colors, {r, g, b, a})
	 return r, g, b, a
      end
      data:mapPixel(extract_color)
      self.colors = colors
      self:compute_size()
   end,
   
   list_available = function (self)
      local list = lume.reduce(
	 lume.map(_lf.getDirectoryItems("assets/palettes/"),
		  function (v)
		     local file = pl.path.splitext(v)
		     return file
	 end),
	 function (_i, _i2)
	    local i, i2 = tostring(_i), tostring(_i2)
	    return string.format("%s %s", i, i2)
      end)
      return list
   end,
   
   is_on_palette = function (self, cx, cy)
		local bx, by, bw, bh = self:get_bounds ()
		return not (cx < bx or cy < by or cx > bx+bw or cy > by+bh)
   end,
   
   find_hovered_tile = function (self)
	  local mx, my = _lm.getPosition()
      if not self:is_on_palette(mx, my) then return end
      local bx, by, bw, bh = self:get_bounds ()
      local s = self.sz
      mx, my = math.floor(mx/s)*s, math.floor((my-self.y)/s)*s
      local id = mx/s + my/s * self.w
      _lg.setColor(1, 1, 1)
			local _id = id+1
			local r, g, b, a = unpack(self.colors[_id])
      _lg.print(string.format("id: %s r:%.2f g:%.2f b:%.2f a:%.2f",_id, r, g, b, a), 300, 30)
      return _id
   end,
   
   update = function (self)
      if Sled.state == "focused" then 
		self.show = true
		self.y = self.offsetY
		self.ph = self.h * self.sz
      elseif Sled.state == "map" then
		self.show = false
	 return
      end
   end,
   
   get_current_color = function (self)
      return unpack(self.colors[self.selected_id])
   end,
   
   draw_outline = function (self)
      _lg.setColor(1, 1, 1, 1)
      _lg.setLineWidth(.1)
      _lg.line(self.pw, 0, self.pw, _lg.getHeight())
   end,
   
   draw = function (self)
      if not self.show then return end
      _lg.setLineWidth(.1)
      local lx, ly = 0, self.offsetY
      self.hovered_id = self:find_hovered_tile ()
      for k, c in ipairs(self.colors) do
	 local r, g, b, a = unpack(c)
	 _lg.setColor(r, g, b, a)
	 _lg.rectangle('fill', lx, ly, self.sz, self.sz)
	 if self.hovered_id then
	    if self.hovered_id == k then
			_lg.setLineWidth(1)
	       _lg.setColor(1,1,1)
	       _lg.rectangle('line', lx, ly, self.sz, self.sz)
	       if _lm.isDown(1) then
		  self.selected_id = k
	       end
	    end
	 end
	 if self.selected_id == k then
	    _lg.setColor(1, 1, 1, .6)
	    _lg.rectangle('line', lx, ly, self.sz, self.sz)
	 end
	 lx = lx + self.sz
	 if k%self.tile_margin == 0 then
	    ly = ly + self.sz
	    lx = 0
	 end
      end
      self:draw_outline (outline)
   end,
   
}
